use std::fmt;

trait Man {
    fn say(&self);
    fn eat(&self);
}

// 带泛型的结构体
#[derive(Debug)]
struct Person<T> {
    name: String,
    age: u32,
    data: T,
}

impl<T> Person<T> {
    fn new(name: &str, age: u32, data: T) -> Person<T>{
        Person{
            name: name.to_string(),
            age: age,
            data: data
        }
    }
}

// 实现某个trait方法的struct
impl<T> Man for Person<T>{
    fn say(&self){
        println!("hi i'm {}", self.name)
    }
    fn eat(&self){
        println!("i'm {} years old, and eating food now.", self.age)
    }
}

#[test]
fn test_person(){
    let james = Person::new("james", 18, "123");
    trait_call(&james);

    println!("{:?}.data = {:?}",james.name, james.data);
}

// trait调用必须使用泛型标注
fn trait_call<T: Man>(man: &T) {
    man.say();
    man.eat();
}

// ================================ trait继承 ===========================

// 带父trait的trait
trait Run : Man {
    // 允许有run()的默认实现
    fn run(&self) {
        self.eat();
        self.say();
    }
}

// 可以有默认实现,
impl<T> Run for Person<T> {
    // 可以为空，也可以覆盖默认run实现
//    fn run(&self) {
//        println!("this is a impl run.");
//    }
}

#[test]
fn test_run(){
    let james = Person{
        name: "james".to_string(),
        age: 24,
        data: "haha",
    };

    // 调用run()
    james.run();
}


// ================================ wrapper trait =============================

struct U32(String);

impl fmt::Display for U32 {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "111111")
    }
}

#[test]
fn test_trait_wrapper(){
    let s = U32("134".to_string());
    println!("{}", s);
}
